package com.lap.service.starter.tools;

import jakarta.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;
import org.springframework.http.server.ServletServerHttpRequest;

/**
 * 客户端获取ip工具
 *
 * @author Shuisheng Lao(劳水生)
 * @version 0.0.1
 */
public final class ClientIpUtil {
  private static final String LOCALHOST = "127.0.0.1";

  private static final List<String> LOCAL_ADDRESSES =
      List.of(LOCALHOST, "0:0:0:0:0:0:0:1", "localhost");

  /** 请求头信息 */
  private static final List<String> HEADERS =
      List.of(
          "http_x_forwarded_for",
          "x-forwarded-for",
          "x-real-ip",
          "proxy-client-ip",
          "wl-proxy-client-ip",
          "http_client_ip");

  private ClientIpUtil() {
    // 防止实例化
  }

  public static String getClientIp(HttpServletRequest request) {
    if (request == null) return LOCALHOST;

    return HEADERS.stream()
        .map(request::getHeader)
        .map(ClientIpUtil::extractValidIp)
        .filter(Objects::nonNull)
        .findFirst()
        .orElse(LOCALHOST);
  }

  public static String getClientIp(ServletServerHttpRequest request) {
    if (request == null) return LOCALHOST;
    return HEADERS.stream()
        .map(request.getHeaders()::getFirst)
        .map(ClientIpUtil::extractValidIp)
        .filter(Objects::nonNull)
        .findFirst()
        .orElse(LOCALHOST);
  }

  private static String extractValidIp(String ip) {
    if (ip == null || ip.isEmpty()) return null;

    String extractedIp = ip.contains(",") ? ip.substring(0, ip.indexOf(",")).trim() : ip.trim();
    return LOCAL_ADDRESSES.contains(extractedIp) ? null : extractedIp;
  }
}
